﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using MyRabbit.EntityFrameWorkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace MyRabbit.Repositories
{
    public class Repository<T> : IRepository<T> where T : class
    {
        /// <summary>
        /// 上下文
        /// </summary>
        private readonly MyRabbitDbContext db;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="db"></param> 
        public Repository(MyRabbitDbContext db)
        {
            this.db = db;
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> InsertManyAsync(IEnumerable<T> entities)   
        {

            await db.Set<T>().AddRangeAsync(entities);
            return await db.SaveChangesAsync();

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>返回是影响的行数</returns>

        public async Task<int> DeleteAsync(T entity)
        {
            db.Set<T>().Remove(entity);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 查询全部
        /// </summary>
        /// <returns></returns>
        public async Task<List<T>> GetAllAsync()
        {
            return await db.Set<T>().ToListAsync();
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>返回添加实体</returns>
        public async Task<T> InsertAsync(T entity)
        {
            try
            {
                await db.Set<T>().AddAsync(entity);
                await db.SaveChangesAsync();
                return entity;
            }
            catch (Exception ex)
            {

                throw;
            }
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> UpdateAsync(T entity)
        {
            db.Set<T>().Update(entity);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 根据 ID 获取单个实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T> GetByIdAsync(int id)
        {
            return await db.Set<T>().FindAsync(id);
        }

        /// <summary>
        /// 根据条件表达式获取单个实体
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<T> GetByConditionAsync(Expression<Func<T, bool>> condition)
        {
            return await db.Set<T>().FirstOrDefaultAsync(condition);
        }

        /// <summary>
        /// 根据条件表达式获取多个实体
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<List<T>> GetManyByConditionAsync(Expression<Func<T, bool>> condition)
        {
            return await db.Set<T>().Where(condition).ToListAsync();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> DeleteManyAsync(IEnumerable<T> entities)
        {
            db.Set<T>().RemoveRange(entities);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> UpdateManyAsync(IEnumerable<T> entities)
        {
            db.Set<T>().UpdateRange(entities);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 根据条件表达式获取多个实体并排序
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="condition"></param>
        /// <param name="orderby"></param>
        /// <param name="Dol"></param>
        /// <returns></returns>

        public async Task<List<T>> GetManyByConditionAsync<TKey>(Expression<Func<T, bool>> condition, Expression<Func<T, TKey>> orderby, bool Dol)
        {

            if (Dol)
            {

                return await db.Set<T>().Where(condition).OrderBy(orderby).ToListAsync();
            }
            else
            {
                return await db.Set<T>().Where(condition).OrderByDescending(orderby).ToListAsync();
            }


        }

        public Task<bool> ExistsAsync(Expression<Func<T, bool>> condition)
        {
            throw new NotImplementedException();
        }
    }
}
  